#include "renderoptions.h"


renderoptions::renderoptions()
{
	width = 800;
	height = 600;

	standardSet();
}
renderoptions::renderoptions(unsigned int X, unsigned int Y)
{
	width = X;
	height = Y;

	standardSet();
}
renderoptions::renderoptions(std::string fileName)
{
	std::ifstream plik;

	plik.open(fileName.c_str());

	if (!plik)
	{
		std::cout<<"XMLFAIL";
		width = 800;
		height = 600;
	}
	standardSet();
	char line[MAX_LENGTH];
	plik.getline(line, MAX_LENGTH);
	while(plik!=NULL)
	{
		plik.getline(line, MAX_LENGTH);
		std::string temp(line);
		unsigned int i(0);

		while(temp[i] == 9 || temp[i] == 32)
			++i;

		if(temp[i] == '<')
		{
			++i;
			std::string nazwaWezla;
			std::string nazwaWezlaKoniec;
			std::string zawartoscWezla;

			while(temp[i] != '>')
			{
				nazwaWezla.push_back(temp[i]);
				++i;
			}
			if(nazwaWezla == "renderoptions")
			{
				//yay idziemy dalej
				continue;
			}
			else if(nazwaWezla == "width")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/width")
					setWidth(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "height")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/height")
					setHeight(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "antialiasing")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/antialiasing")
					setAntialasingAlgorithm(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "antialiasingMultiplier")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/antialiasingMultiplier")
					setAntialasingMultiplyier(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "lights")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/lights")
					if(zawartoscWezla == "True")
						lighsOnOff(true);
					else
						lighsOnOff(false);
				continue;
			}
			else if(nazwaWezla == "shades")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/shades")
					if(zawartoscWezla == "True")
						shadesOnOff(true);
					else
						shadesOnOff(false);
				continue;
			}
			else if(nazwaWezla == "reflections")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/reflections")
					if(zawartoscWezla == "True")
						reflectionsOnOff(true);
					else
						reflectionsOnOff(false);
				continue;
			}
			else if(nazwaWezla == "reflectionsPrecision")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/reflectionsPrecision")
					setReflectionsPrecision(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "refractions")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/refractions")
					if(zawartoscWezla == "True")
						refractionsOnOff(true);
					else
						refractionsOnOff(false);
				continue;
			}
			else if(nazwaWezla == "refracionDepth")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/refracionDepth")
					setRefractionsDepth(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "photonsPerSample")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/photonsPerSample")
					setPhotonsPerSample(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "photonSampleRadius")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/photonSampleRadius")
					setPhotonSampleRadius(atof(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "FOV")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/FOV")
					setFOV((float)atof(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "cameraType")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/cameraType")
					setCameraType(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "clipping")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/clipping")
					setClippingDepth(atof(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "sceneDivision")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/sceneDivision")
					if(zawartoscWezla == "True")
						sceneDivisionOnOff(true);
					else
						sceneDivisionOnOff(false);
				continue;
			}
			else if(nazwaWezla == "divisionAlgorithm")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/divisionAlgorithm")
					setDivisionAlgorithm(atoi(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "cornelBox")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/cornelBox")
					if(zawartoscWezla == "True")
						cornelBoxOnOff(true);
					else
						cornelBoxOnOff(false);
				continue;
			}
			else if(nazwaWezla == "exposureContlorl")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/exposureContlorl")
					color::setExposure(atof(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "pixelAspectRatio")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/pixelAspectRatio")
					setpixelAspectRatio(atof(zawartoscWezla.c_str()));
				continue;
			}
			else if(nazwaWezla == "photonMaping")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/photonMaping")
					if(zawartoscWezla == "True")
						photonMapingOnOff(true);
					else
						photonMapingOnOff(false);
				continue;
			}
			else if(nazwaWezla == "photonCount")
			{
				++i;
				while(temp[i] != '<')
				{
					zawartoscWezla.push_back(temp[i]);
					++i;
				}
				++i;
				while(temp[i] != '>')
				{
					nazwaWezlaKoniec.push_back(temp[i]);
					++i;
				}
				if(nazwaWezlaKoniec == "/photonCount")
					setPhotonCount(atoi(zawartoscWezla.c_str()));
				continue;
			}


		}
	}
}
void renderoptions::standardSet()
{
	//renderer
	antialiasing = 0;
	antialiasingMultiplier = 1;

	lights = false;
	shades = false;
	reflections = false;
	reflectionsPrecision = 0; //1x, 2x, etc
	refractions = false;
	refracionDepth = 0; 

	photonMaping = false;
	photonCount = 0;

	//camera
	FOV	= 45;
	cameraType = 0;
	clipping = 100.0;

	//scene
	sceneDivision = false;
	divisionAlgorithm = 0;
	cornelBox = false;
	backgroundMaterial.setDiffuse(color(0.01f,0.01f,0.01f));

	//picture
	pixelAspectRatio = 1.0;
}
renderoptions::~renderoptions()
{

}
void renderoptions::setWidth(unsigned int X)
{
	width = X;
}
void renderoptions::setHeight(unsigned int Y)
{
	height = Y;	
}
void renderoptions::setAntialasingAlgorithm(unsigned int no)
{
	if(no >=0 && no <= ANTIALIASING_ALGORITHMS)
		antialiasing = no;
	else if (no < 0)
		antialiasing = 0;
	else
		antialiasing = ANTIALIASING_ALGORITHMS;
}
void renderoptions::setAntialasingMultiplyier(unsigned int mul)
{
	if(mul >=0 && mul <= MAX_ANTIALIASING_MULTIPLYIER)
		antialiasingMultiplier = mul;
	else if (mul < 0)
		antialiasingMultiplier = 0;
	else
		antialiasingMultiplier = MAX_ANTIALIASING_MULTIPLYIER;
}
void renderoptions::lighsOnOff(bool choice)
{
	lights = choice;
}
void renderoptions::shadesOnOff(bool choice)
{
	shades = choice;
}
void renderoptions::reflectionsOnOff(bool choice)
{
	if(choice)
	{
		reflections = choice;
		reflectionsPrecision = 1;
	}
	else
	{
		reflections = choice;
		reflectionsPrecision = 0;
	}
}
void renderoptions::setReflectionsPrecision(unsigned int precision)
{
	if(precision >=0 && precision <= MAX_REFLECTION_PRECISON)
		reflectionsPrecision = precision;
	else if (precision < 0)
		reflectionsPrecision = 0;
	else
		reflectionsPrecision = MAX_REFLECTION_PRECISON;
}
void renderoptions::refractionsOnOff(bool choice)
{
	if(choice)
	{
		refractions = choice;
		refracionDepth = 1;
	}
	else
	{
		refractions = choice;
		refracionDepth = 0;
	}
}
void renderoptions::setRefractionsDepth(unsigned int depth)
{
	if(depth >=0 && depth <= MAX_REFRACION_DEPTH)
		refracionDepth = depth;
	else if (depth < 0)
		refracionDepth = 0;
	else
		refracionDepth = MAX_REFRACION_DEPTH;
}
void renderoptions::photonMapingOnOff(bool choice)
{
	photonMaping = choice;
}
void renderoptions::setPhotonCount(unsigned int n)
{
	if(n >= 0 && n <= MAX_PHOTONS)
		photonCount = n;
	else if (n < 0)
		photonCount = 0;
	else
		photonCount = MAX_PHOTONS;
}
void renderoptions::setPhotonsPerSample(unsigned int n)
{
	if(n >= 0 && n <= MAX_PHOTONS)
		photonsPerSample = n;
	else if (n < 0)
		photonsPerSample = 0;
	else
		photonsPerSample = MAX_PHOTONS;
}
void renderoptions::setPhotonSampleRadius(double r)
{
	if(r >= 0.0 && r <= MAX_SAMPLE_RADIUS)
		photonSampleRadius = r;
	else if (r < 0.0)
		photonSampleRadius = 0.0;
	else
		photonSampleRadius = MAX_SAMPLE_RADIUS;
}
void renderoptions::setFOV(float fov)
{
	if(fov >= MIN_FOV && fov <= MAX_FOV)
		FOV = fov;
	else if (fov < MIN_FOV)
		FOV = MIN_FOV;
	else
		FOV = MAX_FOV;
}
void renderoptions::setCameraType(unsigned int type)
{
	cameraType = type;
	if(type >=0 && type <= CAMERA_TYPES)
		cameraType = type;
	else if (type < 0)
		cameraType = 0;
	else
		cameraType = CAMERA_TYPES;
}
void renderoptions::setClippingDepth(double depth)
{
	clipping = depth;
}
void renderoptions::sceneDivisionOnOff(bool choice)
{
	if(choice)
	{
		sceneDivision = choice;
		divisionAlgorithm = 1;
	}
	else
	{
		sceneDivision = choice;
		divisionAlgorithm = 0;
	}
}
void renderoptions::setDivisionAlgorithm(unsigned int algorithm)
{
	if(algorithm >= 0 && algorithm <= DIVISION_ALGORITHMS)
		divisionAlgorithm = algorithm;
	else if (algorithm < 0)
		divisionAlgorithm = 0;
	else
		divisionAlgorithm = DIVISION_ALGORITHMS;
}
void renderoptions::cornelBoxOnOff(bool choice)
{
	cornelBox = choice;
}
void renderoptions::setbackgroundMaterial(material background)
{
	backgroundMaterial = background;
}
void renderoptions::setpixelAspectRatio(double AR)
{
	pixelAspectRatio = AR;
}
unsigned int renderoptions::getWidth()
{
	return width;
}
unsigned int renderoptions::getHeight()
{
	return height;
}

unsigned int renderoptions::getAntialasingAlgorithm()
{
	return antialiasing;
}
unsigned int renderoptions::getAntialasingMultiplyier()
{
	return antialiasingMultiplier;
}
bool renderoptions::getLighs()
{
	return lights;
}
bool renderoptions::getShades()
{
	return shades;
}
bool renderoptions::getReflections()
{
	return reflections;
}
unsigned int renderoptions::getReflectionsPrecision()
{
	return reflectionsPrecision;
}
bool renderoptions::getRefractions()
{
	return refractions;
}
unsigned int renderoptions::getRefractionsDepth()
{
	return refracionDepth;
}
bool renderoptions::getPhotonMapping()
{
	return photonMaping;
}
unsigned int renderoptions::getPhotonCount()
{
	return photonCount;
}
unsigned int renderoptions::getPhotonsPerSample()
{
	return photonsPerSample;
}
double renderoptions::getPhotonSampleRadius()
{
	return photonSampleRadius;
}
float renderoptions::getFOV()
{
	return FOV;
}
unsigned int renderoptions::getCameraType()
{
	return cameraType;
}
double renderoptions::getClippingDepth()
{
	return clipping;
}
bool renderoptions::getSceneDivision()
{
	return sceneDivision;
}
unsigned int renderoptions::getDivisionAlgorithm()
{
	return divisionAlgorithm;
}
bool renderoptions::getCornelBox()
{
	return cornelBox;
}
material renderoptions::getBackgroundMaterial()
{
	return backgroundMaterial;
}
double renderoptions::getpixelAspectRatio()
{
	return pixelAspectRatio;
}